package com.nstskj.study.netty.tcp.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.langangkj.core.response.wrap.PageVo;
import com.langangkj.core.response.wrap.PageVoFactory;
import com.nstskj.study.netty.tcp.common.vo.NetDeviceVO;
import com.nstskj.study.netty.tcp.netty.protocol.endpoint.data.EndpointData;
import com.nstskj.study.netty.tcp.netty.protocol.executor.end.DeviceEndpointDataWorkHandlerExecutor;
import com.nstskj.study.netty.tcp.netty.protocol.session.NetDeviceSession;
import com.nstskj.study.netty.tcp.netty.protocol.session.base.AbstractSession;
import com.nstskj.study.netty.tcp.netty.protocol.session.manage.NetDeviceSessionManage;
import com.nstskj.study.netty.tcp.service.NetDeviceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;

/**
 * @author ZhouChuGang
 * @version 1.0
 * @project nstskj-study-netty-tcp-spring
 * @date 2021/4/22 21:24
 * @Description
 */
@Slf4j
@Service
public class NetDeviceServiceImpl implements NetDeviceService {

    @Autowired
    private NetDeviceSessionManage netDeviceSessionManage;

    @Autowired
    private DeviceEndpointDataWorkHandlerExecutor deviceEndpointDataWorkHandlerExecutor;

    @Override
    public PageVo<NetDeviceVO> getNetDeviceList() {
        Collection<AbstractSession> sessions = netDeviceSessionManage.getSessionMap().values();
        List<AbstractSession> abstractSessions = CollUtil.list(false, sessions);
        PageVo<NetDeviceVO> netDeviceVOPageVo = PageVoFactory.originalBuilder(abstractSessions, obj -> {
                    NetDeviceVO netDeviceVO = new NetDeviceVO();
                    netDeviceVO.setHosts(obj.getChannel().remoteAddress().toString());
                    netDeviceVO.setNetDeviceSession((NetDeviceSession) obj);
                    return netDeviceVO;
                }
        );
        return netDeviceVOPageVo;
    }

    /**
     * 关闭指定的设备
     *
     * @param sessionId
     * @return
     */
    @Override
    public boolean closeNetDeviceBySessionId(String sessionId) {
        AbstractSession session = netDeviceSessionManage.getSession(sessionId);
        if (session != null) {
            session.close();
        }
        return true;
    }


    /**
     * 向指定的设备端点地址发送数据
     *
     * @param sessionId
     * @param address
     * @param data
     * @return
     */
    @Override
    public boolean sendAddressDataBySessionId(String sessionId, Short address, Short data) {
        AbstractSession session = netDeviceSessionManage.getSession(sessionId);
        if (session != null) {
            byte[] bytes = {(byte) (address >> 8), (byte) (address & 0XFF), (byte) (data >> 8), (byte) (data & 0XFF)};
            session.sendBytes(bytes);
        }
        return true;
    }

    /**
     * 读取指定会话的端点数据
     *
     * @param sessionId
     * @param address
     * @return
     */
    @Override
    public List<EndpointData> getAddressDataBySessionId(String sessionId, Short address) {
        return deviceEndpointDataWorkHandlerExecutor.getEndpointDataList(sessionId, address);
    }

}
